#ifndef EASYASIO_NET_TCP_SERVER_HPP
#define EASYASIO_NET_TCP_SERVER_HPP

#include <asio.hpp>
#include <string>
#include <vector>
#include <memory>

#include "../base/utils.hpp"
#include "callbacks.hpp"
#include "io_service_pool.hpp"
#include "tcp_connection.hpp"

namespace easyasio {
namespace net {

class TcpServer : private noncopyable
{
public:
	/// Construct the server to listen on the specified TCP address and port, and
	/// serve up files from the given directory.
	explicit TcpServer(const std::string& address, const std::string& port, std::size_t io_service_pool_size);

	/// Run the server's io_service loop.
	void run();

	void setConnectionCallback(const ConnectionCallback& cb) { connectionCallback_ = cb; }
	void setMessageCallback(const MessageCallback& cb) { messageCallback_ = cb; }
	void setWriteCompleteCallback(const WriteCompleteCallback& cb) { writeCompleteCallback_ = cb; }
    void setCloseCallback(const CloseCallback& cb) { closeCallback_ = cb; }

private:
	/// Initiate an asynchronous accept operation.
	void start_accept();

	/// Handle completion of an asynchronous accept operation.
	void handle_accept(const asio::error_code& e);

	/// Handle a request to stop the server.
	void handle_stop();

	/// The pool of io_service objects used to perform asynchronous operations.
	io_service_pool io_service_pool_;

	/// The signal_set is used to register for process termination notifications.
	asio::signal_set signals_;

	/// Acceptor used to listen for incoming connections.
	asio::ip::tcp::acceptor acceptor_;

	/// The next connection to be accepted.
	TcpConnectionPtr new_connection_;

	ConnectionCallback connectionCallback_;
	MessageCallback messageCallback_;
	WriteCompleteCallback writeCompleteCallback_;
    CloseCallback closeCallback_;

};

} // namespace easyasio 
} // namespace net 

#endif // EASYASIO_NET_TCP_SERVER_HPP
